/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

var rdpClientManagers = [];

function WebRDPManager(parentId, messagesId, objectName, hostAddress, machinePorts)
{
    var parentElementId = parentId;
    var messagesElementId = messagesId;
    var objectVariableName = objectName;
    var rdpClient = null;
    var isLoaded = false;
    var isConnected = false;

    var configurationHostAddress = hostAddress;
    var configurationMachinePorts = machinePorts.split(",");
    var configurationMachinePortId = 0;
    var configurationLogonUsername = "";
    var configurationLogonPassword = "";
    var configurationDisplayWidth = "";
    var configurationDisplayHeight = "";
    var isConfigured = false;

    var currentScancodes = "";

    rdpClientManagers[parentElementId] = this;

    initialize();

    function initialize()
    {
        writeToMessageField("Client loading...");
        RDPWebClient.embedSWF ("swf/RDPClientUI.swf", parentElementId);
    }

    this.flagAsLoaded = function()
    {
        isLoaded = true;
        rdpClient = RDPWebClient.getFlashById(parentElementId);
        
        return false;
    }

    this.flagAsConnected = function()
    {
        isConnected = true;

        return false;
    }

    this.flagAsDisconnected = function()
    {
        isConnected = false;

        return false;
    }

    this.getMessagesElementId = function()
    {
        return messagesElementId;
    }

    this.setInitialConfiguration = function(machinePortId, username, password, displayWidth, displayHeight)
    {
        if(!isConfigured)
        {
            configurationMachinePortId = parseInt(machinePortId);
            configurationLogonUsername = username;
            configurationLogonPassword = password;
            configurationDisplayWidth = displayWidth;
            configurationDisplayHeight = displayHeight;
            isConfigured = true;
        }

        return false;
    }

    this.updateConfiguration = function(formId)
    {
        var form = document.getElementById(formId);
        configurationMachinePortId = form.elements['machinePortId'].value;
        configurationLogonUsername = form.elements['logonUsername'].value;
        configurationLogonPassword = form.elements['logonPassword'].value;
        configurationDisplayWidth = form.elements['displayWidth'].value;
        configurationDisplayHeight = form.elements['displayHeight'].value;

        return false;
    }

    this.setScancodes = function(formId)
    {
        if(!isConnected)
            return false;

        var scancodeMatcher = /([0-9a-f]{2})/g;
        var trimmTrailingSpacesMatcher = /(\s*$)/gi;
        var form = document.getElementById(formId);
        var rawCodes = form.elements['scancodes'].value;

        currentScancodes = "";
        var scancodeGroups = rawCodes.split('^');

        for(var i = 0; i < scancodeGroups.length; i++)
        {
            scancodeGroups[i] = scancodeGroups[i].match(scancodeMatcher);

            if(scancodeGroups[i] != null)
            {
                for(var ii = 0; ii < scancodeGroups[i].length; ii++)
                    currentScancodes += scancodeGroups[i][ii] + " ";

                for(var iii = 0; iii < scancodeGroups[i].length; iii++)
                    currentScancodes += (parseInt(scancodeGroups[i][iii], 16) + 128).toString(16) + " ";
            }
            else
                break;
        }

        currentScancodes = currentScancodes.replace(trimmTrailingSpacesMatcher, "");

        return false;
    }

    function writeToMessageField(message)
    {
        var date = new Date();
        document.getElementById(messagesElementId).innerHTML = 
            ((date.getHours() <= 9) ? "0" : "") + date.getHours() + ":"
            + ((date.getMinutes() <= 9) ? "0" : "") + date.getMinutes() + ":"
            + ((date.getSeconds() <= 9) ? "0" : "") + date.getSeconds() + " >: "
            + message;
    }

    this.writeToMessageField = function(message)
    {
        writeToMessageField(message);
    }

    this.connect = function(caller)
    {
        if(!isLoaded || !isConfigured)
            return false;

        caller.innerHTML = 'Disconnect';
        caller.setAttribute('onclick', 'return ' + objectVariableName + '.disconnect(this);');

        if(rdpClient)
        {
            /* Setup the client parameters. */
            rdpClient.setProperty("serverAddress", configurationHostAddress);
            rdpClient.setProperty("serverPort", configurationMachinePorts[configurationMachinePortId]);
            rdpClient.setProperty("logonUsername", configurationLogonUsername);
            rdpClient.setProperty("logonPassword", configurationLogonPassword);
            rdpClient.setProperty("displayWidth", configurationDisplayWidth);
            rdpClient.setProperty("displayHeight", configurationDisplayHeight);

            writeToMessageField("Connecting...");

            /* Establish the connection. */
            rdpClient.connect();
        }

        return false;
    }

    this.disconnect = function(caller)
    {
        if(rdpClient)
            rdpClient.disconnect();

        caller.innerHTML = 'Connect';
        caller.setAttribute('onclick', 'return ' + objectVariableName + '.connect(this);');

        return false;
    }

    this.getProperty = function(propertyName)
    {
        var value = "";
        if(rdpClient)
            value = rdpClient.getProperty(propertyName);

        return value;
    }

    this.sendCAD = function()
    {
        if(rdpClient && isConnected)
        {
            rdpClient.keyboardSendCAD();
            writeToMessageField("CTRL + ALT + DEL sent to guest...");
        }
        
        return false;
    }

    this.sendScancodes = function()
    {
        if(rdpClient && isConnected)
        {
            rdpClient.keyboardSendScancodes(currentScancodes);
            writeToMessageField("Scan codes sent to guest: " + currentScancodes);
        }

        return false;
    }
}

function RDPWebEventLoaded(flashId)
{
    /* The movie loading is complete, the flash client is ready. */
    rdpClientManagers[flashId].flagAsLoaded();
    rdpClientManagers[flashId].writeToMessageField("Client loaded...");
}

function RDPWebEventConnected(flashId)
{
    /* RDP connection has been established */
    rdpClientManagers[flashId].flagAsConnected();
    rdpClientManagers[flashId].writeToMessageField("Connection established...");
}

function RDPWebEventServerRedirect(flashId)
{
    /* RDP connection has been established */
    rdpClientManagers[flashId].writeToMessageField("Server redirect...");
}

function RDPWebEventDisconnected(flashId)
{
    /* RDP connection has been lost */
    rdpClientManagers[flashId].flagAsDisconnected();
    rdpClientManagers[flashId].writeToMessageField("Disconnected: "
        + rdpClientManagers[flashId].getProperty("lastError"));
}